67 _ 基于云计算的无服务架构

你好,我是周志明。

首先我们要知道,无服务架构(Serverless)跟微服务架构本身没有继承替代的关系,它们并不是同一种层次的架构,无服务的云函数可以作为微服务的一种实现方式,甚至可能是未来很主流的实现方式。在课程中,我们的话题主要还是聚焦在如何解决分布式架构下的种种问题,所以相对来说,无服务架构并不是重点,不过为了保证架构演进的完整性,我仍然建立了无服务架构的简单演示工程。

另外还要明确一点,由于无服务架构在原理上就决定了它对程序的启动性能十分敏感,这天生就不利于Java程序,尤其不利于Spring这类启动时组装的CDI框架。因此基于Java的程序,除非使用GraalVM做提前编译、将Spring的大部分Bean提前初始化,或者迁移至Quarkus这种以原生程序为目标的框架上,否则是很难实际用于生产的。

运行程序

Serverless架构的Fenix’s Bookstore是基于亚马逊AWS Lambda平台运行的,这是最早商用,也是目前全球规模最大的Serverless运行平台。不过从2018年开始,中国的主流云服务厂商,比如阿里云、腾讯云也都推出了各自的Serverless云计算环境,如果你需要在这些平台上运行Fenix’s Bookstore,你要根据平台提供的Java SDK对StreamLambdaHandler的代码做少许调整。

现在,假设你已经完成了AWS注册、配置AWS CLI环境以及IAM账号的前提下,就可以通过以下几种途径来运行程序,浏览最终的效果:

  • 通过AWS SAM(Serverless Application Model) Local在本地运行:

AWS CLI中附有SAM CLI,但是版本比较旧,你可以通过如下地址安装最新版本的SAM CLI。另外,SAM需要Docker运行环境支持,你可参考此处部署。

首先编译应用出二进制包,执行以下标准Maven打包命令即可:

$ mvn clean package

根据pom.xml中assembly-zip的设置,打包将不会生成SpringBoot Fat JAR,而是产生适用于AWS Lambda的ZIP包。打包后,确认已经在target目录生成了ZIP文件,并且文件名称与代码中提供的sam.yaml配置的一致,然后在工程根目录下运行如下命令,启动本地SAM测试:

$ sam local start-api --template sam.yaml

在浏览器访问:http://localhost:3000,系统预置了一个用户(user:icyfenix,pw:123456),你也可以注册新用户来测试。

  • 通过AWS Serverless CLI将本地ZIP包上传至云端运行:

在确认已经配置了AWS凭证后,工程中已经提供了serverless.yml配置文件,确认文件中ZIP的路径与实际Maven生成的一致,然后在命令行执行:

$ sls deploy

此时,Serverless CLI会自动将ZIP文件上传至AWS S3,然后生成对应的Layers和API Gateway,运行结果如下所示:

$ sls deploy
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service bookstore-serverless-awslambda-1.0-SNAPSHOT-lambda-package.zip file to S3 (53.58 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............
Serverless: Stack update finished...
Service Information
service: spring-boot-serverless
stage: dev
region: us-east-1
stack: spring-boot-serverless-dev
resources: 10
api keys:
  None
endpoints:
  GET - https://cc1oj8hirl.execute-api.us-east-1.amazonaws.com/dev/
functions:
  springBootServerless: spring-boot-serverless-dev-springBootServerless
layers:
  None
Serverless: Removing old service artifacts from S3...

访问输出结果中的地址(比如上面显示的https://cc1oj8hirl.execute-api.us-east-1.amazonaws.com/dev/)即可浏览结果。

这里要注意,由于Serverless对响应速度的要求本来就较高,所以我不建议再采用HSQLDB数据库来运行程序了,毕竟每次冷启动都重置一次数据库本身也并不合理。代码中有提供MySQL的Schema,我建议采用AWS RDB MySQL/MariaDB作为数据库来运行。

协议

课程的工程代码部分采用Apache 2.0协议进行许可。在遵循许可的前提下,你可以自由地对代码进行修改、再发布,也可以将代码用作商业用途。但要求你:

  • 署名:在原有代码和衍生代码中,保留原作者署名及代码来源信息;
  • 保留许可证:在原有代码和衍生代码中,保留Apache 2.0协议文件。